//package com.fangliai.common.redis.aop;
//
//import com.jiaai.common.redis.RedisUtils;
//import com.jiaai.common.util.ReflectUtils;
//import com.jiaai.common.util.str.StringUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.redisson.api.RMapCache;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.TimeUnit;
//
//@Component
//@Aspect
//public class CacheAspect {
//    private static  final Logger log= LoggerFactory.getLogger(CacheAspect.class);
//    @Autowired
//    private RedisUtils redisUtils;
//
//    private ThreadLocal<Long> time=new ThreadLocal<Long>();
//    private ThreadLocal<String> tag=new ThreadLocal<String>();
//
//
//    @Pointcut("@annotation(com.jiaai.common.redis.aop.RedisCache)")
//    public void cachePointcut() {}
//
//
//
//
//
//
//    /**
//     * 读取绶存
//     * @param point
//     */
//    @Around("cachePointcut()")
//    public  Object doAround(ProceedingJoinPoint point){
//        Object[] args = point.getArgs();
//
//        MethodSignature methodSignature = (MethodSignature) point.getSignature();
//        Method method = methodSignature.getMethod();
//        RedisCache cacheinfo = method.getAnnotation(RedisCache.class);
//
//        Object obj= null;
//        switch (cacheinfo.action()){
//            case DEL:
//                  delCache(method,args,cacheinfo);
//                break;
//            case PUT:
//                delCache(method,args,cacheinfo);
//                break;
//            default:
//                log.info("方法"+method.getName()+"，尝试从缓存获取...");
//                return getCache(point,cacheinfo);
//        }
//
//        return obj;
//    }
//
//    private void delCache(Method method,Object[] args,RedisCache cache){
//        List<List<String>> delKeyConfigs=new ArrayList<>();
//        switch (cache.action()){
//            case DEL:
//                 delKeyConfigs.add(getDelCacheConfig(method,args,cache.cacheName()+"#"+cache.key()));
//                 break;
//            case PUT:
//                  if(cache.synchroDel()!=null && cache.synchroDel().length>0){
//                      for (String delKey:cache.synchroDel()) {
//                         delKeyConfigs.add(getDelCacheConfig(method,args,delKey));
//                      }
//                  }
//                 break;
//
//        }
//        delKeyConfigs.forEach(v->{
//             delCacheByKey(v);
//        });
//    }
//    /**
//     * 获取需要删除的key适配Map结枸
//     * 如果在小>1 则0：Key 1：filed
//     * @param method
//     * @param args
//     * @param key
//     * @return
//     */
//    private List<String> getDelCacheConfig(Method method,Object[] args,String key){
//        List<String> config=new ArrayList<>();
//        if(key.indexOf("#")>0){
//            String[] kk=key.split("#");
//            if(kk.length>0){
//                config.add(kk[0]);
//                config.add(getCacheKey(method,args,kk[1]));
//            }
//        }else{
//           config.add(getCacheKey(method,args,key));
//        }
//        return config;
//    }
//
//    private void delCacheByKey(List<String> keys){
//          if(keys.size()>1){
//              try {
//                  redisUtils.getRMapCache(keys.get(0)).removeAsync(keys.get(1)).get();
//              } catch (Exception e) {
//                  log.error(String.format("删除绶存[%s,%s]失败,error:%s",keys.get(0),keys.get(1),e.getMessage()));
//              }
//          }else {
//              try {
//                  redisUtils.getRBucket(keys.get(0)).deleteAsync().get();
//              } catch (Exception e) {
//                  log.error(String.format("删除绶存[%s]失败,error：%s"),keys.get(0),e.getMessage());
//              }
//          }
//
//    }
//    /**
//     * 从绶存中读取，没有则读取db
//     * @param point
//     * @param redisCache
//     * @return
//     */
//    private Object getCache(ProceedingJoinPoint point,RedisCache redisCache){
//        Object[] args = point.getArgs();
//        MethodSignature methodSignature = (MethodSignature) point.getSignature();
//        Method method = methodSignature.getMethod();
//
//         Object obj=null;
//         String key=getCacheKey(method,args,redisCache.key());
//         if(StringUtils.isEmpty(redisCache.cacheName())){
//             obj=redisUtils.getRBucket(key).get();
//         }else {
//             RMapCache<String,Object> map=redisUtils.getRMapCache(redisCache.cacheName());
//             try {
//                 obj=map.getAsync(key).get();
//             } catch (Exception e) {
//                log.error(String.format("读取绶存[%s,%s]失败",redisCache.cacheName(),key));
//             }
//         }
//         if(obj!=null){
//             log.error(String.format("方法[%s],命中绶存",method.getName()));
//         }else {
//             log.error(String.format("方法[%s],未命中绶存",method.getName()));
//             try {
//                 obj=point.proceed();
//                 if(StringUtils.isEmpty(redisCache.cacheName())){
//                     if(redisCache.expiry()>0){
//                         redisUtils.getRBucket(key).set(obj,redisCache.expiry(), TimeUnit.MINUTES);
//                     }else {
//                         redisUtils.getRBucket(key).set(obj);
//                     }
//                 }else {
//                     if(redisCache.expiry()>0){
//                         redisUtils.getRMapCache(redisCache.cacheName()).put(key,obj,redisCache.expiry(),TimeUnit.MINUTES);
//                     }else {
//
//                         redisUtils.getRMapCache(redisCache.cacheName()).put(key,obj);
//                     }
//                 }
//             } catch (Throwable throwable) {
//                 throwable.printStackTrace();
//             }
//         }
//
//        return obj;
//    }
//
//    /***
//     * 获取绶存key
//     * @param method
//     * @param args
//     * @param cacheKey
//     * @return
//     */
//    private String getCacheKey(  Method method,Object[] args,String cacheKey){
//        String key="";
//        if(cacheKey.indexOf("#")>0){
//            String[] params=cacheKey.split("#");
//            for (String param:params) {
//                key+=formatKey(method,args,param);
//            }
//        }else {
//            key+=formatKey(method,args,cacheKey);
//        }
//        return key;
//    }
//
//    /***
//     * 解析绶存key
//     * @param method
//     * @param ob
//     * @param param
//     * @return
//     */
//    private String formatKey(Method method,Object[] ob,String param) {
//        String key = "";
//            if (param.indexOf(".") > 0) { //是对像类型参数
//                String[] pp = param.split("\\.");
//                if (pp.length > 1) {
//                    try {
//                        int index = Integer.valueOf(pp[0].replace("p", ""));
//                        key += getValue(ob[index], pp[1]);
//                    } catch (Exception e) {
//                        log.warn(String.format("方法[%s],绶存参数配置出错[%s]参数下示不是一个有效的数字", method.getName(), param));
//                        key += param;
//                    }
//                } else {
//                    key += param;
//                    log.warn(String.format("方法[%s],绶存参数配置出错[%s],格式为p[索引].[属性]", method.getName(), param));
//                }
//            } else {//基本类型
//                if (param.indexOf("p") == 0) {
//                    try {
//                        int index = Integer.valueOf(param.replace("p", ""));
//                        key += getValue(ob[index], param);
//                    } catch (Exception e) {
//                        log.warn(String.format("方法[%s],绶存参数配置出错[%s]参数下示不是一个有效的数字", method.getName(), param));
//                        key += param;
//                    }
//                } else {
//                    key += param;
//                }
//            }
//            return  key;
//
//    }
//
//    private String getValue(Object ob,String filed){
//        if(ob instanceof String){
//            return ob.toString();
//        }
//         if (ob instanceof Map){
//             return ((Map) ob).get(filed).toString();
//         }
//        return ReflectUtils.invokeGetter(ob,filed).toString();
//    }
//}